package lynch.display
{
	import com.greensock.TweenNano;
	import flash.geom.Point;
	import lynch.Core.config.ration.Core.config.
	import starling.display.DisplayObject;
	import starling.display.Sprite;
	import starling.events.Event;
	import starling.events.Touch;
	import starling.events.TouchEvent;
	
	/**
	 * ...
	 * @author 小痛
	 */
	public class Container extends Sprite
	{
		/**
		 * 标示,供记录使用
		 **/
		public var customVars:*;
		
		/**
		 * 是否可拖拽
		 */
		private var _dragEnabled:Boolean;
		private var dragXY:Point;
		
		/**
		 * 拖拽是否允许拖出屏幕
		 * 为true时,可以拖拽出屏幕范围,
		 * 为false时将被限定在屏幕范围内
		 */
		public var dragAllowOutScreen:Boolean;
		/**
		 * 用于判断当点击到哪一个子元件时会触发拖拽
		 * 如果想点击该容器任何地方都触发拖拽,设置该值为null
		 */
		public var dragTarget:* = null;
		
		/**
		 * dragAllowOutScreen = false 时拖拽时定位用的
		 */
		private var parnetPoint:Point;
		/**
		 * 当鼠标点击时是否可以自动到父级最前
		 */
		private var _autoToTOP:Boolean;
		
		public function Container()
		{
			super();
			dragTarget = this;
		}
		
		public function addChildren(v:Vector.<DisplayObject>):Vector.<DisplayObject>
		{
			for each (var child:DisplayObject in v) 
			{
				child.removeFromParent();
                child.arcane::setParent(this);                
                child.dispatchEvent(new Event(Event.ADDED, true));
                if (stage) child.dispatchEventOnChildren(new Event(Event.ADDED_TO_STAGE));
			}
			mChildren = mChildren.concat(v);
			return v;
		}
		
		override public function dispose():void 
		{
			customVars = dragTarget = null;
			super.dispose();
		}
		
		//--------------------------------getter / setter-----------
		/**
		 * 设置 / 获取 是否可被鼠标拖动
		 */
		public function get dragEnabled():Boolean
		{
			return _dragEnabled;
		}
		
		public function set dragEnabled(value:Boolean):void
		{
			_dragEnabled = value;
			if (value)
			{
				if(!hasEventListener(TouchEvent.TOUCH))
					addEventListener(TouchEvent.TOUCH, onMouseDownHandler);
			}
			else
			{
				if(_autoToTOP == false)
					removeEventListener(TouchEvent.TOUCH, onMouseDownHandler);
				
				stage.removeEventListener(TouchEvent.TOUCH, onDragTouchHandler);
			}
		}
		
		/**
		 * 设置 / 获取 鼠标点击后是否自动到父级最前端
		 */
		public function get autoToTOP():Boolean
		{
			return _autoToTOP;
		}
		
		public function set autoToTOP(value:Boolean):void
		{
			_autoToTOP = value;
			if (value)
			{
				if(!hasEventListener(TouchEvent.TOUCH))
					addEventListener(TouchEvent.TOUCH, onMouseDownHandler);
			}
			else
			{
				if(_dragEnabled == false)
					removeEventListener(TouchEvent.TOUCH, onMouseDownHandler);
			}
		}
		
		//---------------Event Handler------------------------------------
		private function onMouseDownHandler(e:TouchEvent):void
		{
			//@see TouchPhase
			var touch:Touch = e.getTouch(this, "began");
			if (touch == null)
				return;
			
			if (_autoToTOP)
				parent.setChildIndex(this, parent.numChildren - 1);
			
			if(_dragEnabled == false)
				return;
			
			if (dragTarget == this)
			{
				if(!contains(dragTarget))
					return;
			} else if (touch.target != dragTarget)
			{
				return
			}
			
			var localPoint:Point = new Point();
			parnetPoint = parent.globalToLocal(localPoint);
			
			localPoint = touch.getLocation(this);
			dragXY = new Point(localPoint.x - parnetPoint.x, localPoint.y - parnetPoint.y);
			
			stage.addEventListener(TouchEvent.TOUCH, onDragTouchHandler);
		}
		
		/**
		 * 鼠标按下并移动时拖拽
		 *
		 * 当鼠标弹起时停止拖拽
		 * @param	e
		 */
		private function onDragTouchHandler(e:TouchEvent):void
		{
			var touches:Vector.<Touch> = e.touches;
			
			for each (var touch:Touch in touches)
			{
				if (touch.phase == "moved")
				{
					x = (touch.globalX - dragXY.x) >> 0;
					y = (touch.globalY - dragXY.y) >> 0;
				}
				else if (touch.phase == "ended")
				{
					if (!dragAllowOutScreen)
					{
						var toX:int = x;
						var toY:int = y;
						
						(x + width - parnetPoint.x > Core.config.stageWidth) && (toX = Core.config.stageWidth - width + parnetPoint.x);
						(y + height - parnetPoint.y > Core.config.stageHeight) && (toY = Core.config.stageHeight - height + parnetPoint.y);
						(x - parnetPoint.x < 0) && (toX = parnetPoint.x);
						(y - parnetPoint.y < 0) && (toY = parnetPoint.y);
						
						TweenNano.to(this, .3, {x: toX, y: toY});
					}
					
					stage.removeEventListener(TouchEvent.TOUCH, onDragTouchHandler);
					parnetPoint = dragXY = null;
				}
			}
		}
	}

}